package com.evision.webcrawler.baidu;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.fluent.Request;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;

/**
 * @author xiang
 *         单元爬虫,完成Url请求响应处理
 */
public class CrawlerCell implements Runnable, org.apache.http.client.ResponseHandler<String> {
    private ExecutorService executor;                //任务执行线程池
    private BlockingQueue<RequestUrl> inputQueue;    //输入队列
    private BlockingQueue<RequestUrl>[] outputQueue;    //输出队列

    private Parser parser;                            //结果解析器
    private boolean overflag = false;                //结束标志
    private long thinkingTime = 0L;                    //循环执行的Thinking Time
    private int connectTimeout = 3000;                    //链接的超时时间
    private int socketTimeout = 3000;                    //socket超时时间
    private RequestUrl ru;                            //请求Url

    /**
     * 单元爬虫,完成Url请求响应处理
     *
     * @param e            任务执行线程池
     * @param i            输入队列
     * @param o            输出队列
     * @param p            结果解析器
     * @param thinkingTime 循环执行的ThinkingTime
     */
    public CrawlerCell(ExecutorService e, BlockingQueue<RequestUrl> i,
                       BlockingQueue<RequestUrl>[] o, Parser p, int thinkingTime) {
        this.executor = e;
        this.inputQueue = i;
        this.outputQueue = o;
        this.parser = p;
        this.thinkingTime = thinkingTime;
    }

    /**
     * 单元爬虫单元爬虫实现
     */
    @Override
    public void run() {
        if (this.inputQueue == null) {
            System.out.println("No input queue defined.");
            return;
        }

        if (this.executor == null) {
            System.out.println("No executor defined.");
            return;
        }

        while (!overflag) {
            try {
                Thread.sleep(this.thinkingTime);
                ru = inputQueue.take();
                if (ru.isOver()) {
                    if (this.inputQueue != null)
                        this.inputQueue.put(new RequestUrl(null, true));
                    if (this.outputQueue != null) {
                        for (int i = 0; i < this.outputQueue.length; i++) {
                            this.outputQueue[i].put(new RequestUrl(null, true));
                        }
                    }
                    break;
                } else {
                    try {
                        if (ru.getUrl() != null) {
                            URI uri = new URI(ru.getUrl());
                            Request.Get(uri).addHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8")
                                    .addHeader("Accept-Encoding", "gzip, deflate, sdch")
                                    .addHeader("Accept-Language", "zh-CN,zh;q=0.8")
                                    .addHeader("Cache-Control", "max-age=0")
                                    .addHeader("Connection", "keep-alive")
                                    .addHeader("Cookie", "wdcid=7ab25e450fd3c89f; wdlast=1491025711")
                                    //.addHeader("Host", "image.baidu.com")
                                    .addHeader("Upgrade-Insecure-Requests", "1")
                                    .addHeader("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36")
                                    .connectTimeout(this.connectTimeout)
                                    .socketTimeout(this.socketTimeout).execute().handleResponse(this);
                        }
                    } catch (IOException e1) {
                        e1.printStackTrace();
                    }
                }
            } catch (InterruptedException e2) {
                e2.printStackTrace();
            } catch (URISyntaxException e3) {
                e3.printStackTrace();
            }
        }
        System.out.println("Thread [" + Thread.currentThread().getName() + "] over.");
    }

    @Override
    public String handleResponse(HttpResponse response)
            throws ClientProtocolException, IOException {
        this.parser.parser(response, this.outputQueue, ru);
        return null;
    }
}
